import os
import re
import time
import traceback

import requests


def call(api: str, data: dict | list):
    url = 'http://pcserver.touni.top:9000/yunqing/execute'
    headers = {
        "accept": "application/json",
        "Content-Type": "application/json"
    }
    body_data = {
        'api': api,
        'data': data
    }
    resp = requests.post(url, headers=headers, json=body_data)
    if resp.status_code != 200:
        _console(resp.text)
        raise ValueError('接口调用失败')
    _result = resp.json()
    if _result['code'] != 0:
        _console(resp.text)
        raise ValueError('云擎内部错误')
    return _result


def call_download(api: str, data: dict, filename: str):
    url = 'http://pcserver.touni.top:9000/yunqing/download?filename=' + filename
    headers = {
        "accept": "application/json",
        "Content-Type": "application/json"
    }
    data = {
        'api': api,
        'data': data
    }
    resp = requests.post(url, headers=headers, json=data)
    if resp.status_code != 200:
        _console(resp.text)
        raise ValueError('接口调用失败')
    _result = resp.json()
    if _result['code'] != 0:
        _console(resp.text)
        raise ValueError('云擎内部错误')
    return _result


def call_script(ipmi_ip):
    """调用云擎脚本"""
    data = {
        'api': '/wb/api/v1/task/taskExecute',
        'data': {
            "credentialId": 12328,
            "hostInfo": [
                "121wi7POOy"
            ],
            "hostType": 0,
            "taskId": "3BSiRxfM",
            "versionId": 10006440,
            "tenantId": 282,
            "taskExecuteParamsInList": [
                {
                    "taskParamId": "aP8mqx17",
                    "paramType": 0,
                    "paramName": "ipmi_ip",
                    "paramVal": ipmi_ip,
                    "paramInOut": 0,
                    "taskVerId": 10006440,
                    "versionName": "20250212180448",
                    "paramDesc": "",
                    "bucketName": None,
                    "fileId": None
                }
            ],
            "approvalType": 0,
            "interpreter": "/bin/sh",
            "executeType": 0
        }
    }
    url = 'http://pcserver.touni.top:9000/yunqing/execute'
    headers = {
        "accept": "application/json",
        "Content-Type": "application/json"
    }

    resp = requests.post(url, headers=headers, json=data)
    if resp.status_code != 200:
        _console(resp.text)
        raise ValueError('查询数据失败')

    result = resp.json()
    if result['code'] != 0:
        _console('error', result)
        raise ValueError(result['msg'])

    return result['data']['otherObj']


def get_script_result(task_id):
    """获取云擎脚本执行结果"""
    url = 'http://pcserver.touni.top:9000/yunqing/execute'
    headers = {
        "accept": "application/json",
        "Content-Type": "application/json"
    }

    data = {
        'api': '/wb/api/v1/task/getHostScriptRecordOut',
        'data': {
            "page": 1,
            "rows": 50,
            "filter": {
                "taskExecId": task_id,
                "execStatus": 2
            }
        }
    }
    response = requests.post(url, headers=headers, json=data, verify=False, timeout=10)

    if response.status_code != 200:
        print('response', response.text)
        raise ValueError('接口请求失败')

    return response.json()


def get_task_list():
    """查询云擎任务列表，进行删除云擎拷贝文件任务 """
    data = {
        "page": 1,
        "rows": 50,
        "filter": {
            "taskState": 5,
            "taskType": 1,
            "poolIds": [
                "BJtZflvl"
            ]
        }
    }
    result = call('/wb/api/v1/hostFileTask/getHostFileTaskList', data)

    return result['data']['result']['rows']


def delete_files():
    files = get_task_list()
    for row in files:
        if row["taskName"] == "file-cp":
            call('/wb/api/v1/hostFileTask/deleteHostFileTask', row)
            _console('云擎备份任务清理成功')


def filebackup_add_task(filename):
    _console('下载云擎文件：', filename)
    data = {
        "taskName": "file-cp",
        "taskDesc": "",
        "aimPath": "UbmWat6t",
        "credentialId": 10000333,
        "cronExeMode": 0,
        "periodValue": 1,
        "periodIdx": [],
        "sourceFilePath": filename,
        "hostType": 0,
        "hostInfo": [
            "121wi7POOy"
        ],
        "taskType": 1,
        "fileName": "file",
        "isPrivate": 1,
        "directoryId": "UbmWat6t",
        "poolId": "BJtZflvl",
        "targetPoolId": "BJtZflvl"
    }
    call('/wb/api/v1/hostFileTask/addHostFileTask', data)

    tasks = get_task_list()
    backup_task_id = None
    for task in tasks:
        if task["taskName"] == "file-cp":
            if task['sourceFilePath'] == filename:
                backup_task_id = task["hfId"]
                break
    if not backup_task_id:
        raise ValueError('获取备份任务失败')

    data = {
        "hfId": backup_task_id
    }
    backup_task_result = call('/wb/api/v1/hostFileTask/execTask', data)
    print(backup_task_result)
    if backup_task_result['code'] != 0:
        raise ValueError('备份任务执行失败')

    data = {
        "fileName": "",
        "parentId": "UbmWat6t",
        "tagSet": [],
        "isPrivate": "1",
        "tenantId": 282
    }
    _index = 0
    while _index < 30:
        files_result = call('/wb/api/v1/minio/getResourceList', data)
        file_list = files_result['data']['result']['fileDirInfoOutputList']
        if file_list:
            break
        _index += 2
        time.sleep(2)

    file_info = file_list[0]
    data = {
        "fileName": "",
        "parentId": file_info['id'],
        "tagSet": [],
        "isPrivate": "1",
        "tenantId": 282
    }
    _index = 0
    while _index < 30:
        file_info_result = call('/wb/api/v1/minio/getResourceList', data)
        file_info = file_info_result['data']['result']['fileInfoOutputList']
        if file_info:
            break
        _index += 2
        time.sleep(2)

    file_info = file_info[0]
    data = {
        "fileId": file_info['id'],
        "tenantId": 282
    }

    download_result = call_download('/wb/api/v1//minio/downloadDocument', data, file_info['fileName'])
    _console('下载云擎文件成功：', download_result)
    file_ids = [x['id'] for x in file_list]
    call('/wb/api/v1/minio/deleteFolder', file_ids)
    _console('云擎文件清理成功')
    return download_result['data']['filename']


def main():
    task_id = call_script(ipmi_ip)
    _console('云擎脚本调用成功', task_id)
    _index = 0
    script_output = ''
    while _index < 120:
        result = get_script_result(task_id)
        if result['data']['result']['rows']:
            script_output = result['data']['result']['rows'][0]['execResult']
            break
        _console('带外日志文件下载中……')
        _index += 1
        time.sleep(5)

    path = re.findall(r'日志已保存至：(.*)', script_output)
    if path:
        path = path[0]
    _console('带外日志文件下载成功：', path)
    try:
        filename = filebackup_add_task(path)
    except Exception as e:
        _console('error', e)
        traceback.print_exc()
        return

    save_path = 'depository/BMC日志'
    url = 'http://pcserver.touni.top:9000/yunqing/download-file'
    headers = {
        "accept": "application/json",
        "Content-Type": "application/json"
    }
    params = {
        'filename': filename
    }
    _console('下载文件中', filename)
    response = requests.get(url, headers=headers, params=params, verify=False)
    response.raise_for_status()
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    with open(save_path + '/' + filename, 'wb') as f:
        for chunk in response.iter_content(chunk_size=8192):
            f.write(chunk)
        _console(f"保存文件成功 {save_path + '/' + filename}")

    # 打开目录
    os.startfile(os.path.join(os.getcwd(), save_path))
    delete_files()
